﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Drawing;

namespace BL
{
    [Serializable()]
    public class cTeam
    {
        public delegate void PlayerUpdateListener(cTeam team, cPlayer player);
        [field: NonSerialized] public event PlayerUpdateListener PlayerLocationUpdate;
        [field: NonSerialized] public event PlayerUpdateListener PlayerHasFlag;
        [field: NonSerialized] public event PlayerUpdateListener PlayerIsDead;
        [field: NonSerialized] public event PlayerUpdateListener PlayerReturnedFlag;
        [field: NonSerialized] public event PlayerUpdateListener PlayerInSpawnPoint;
        [field: NonSerialized] public event PlayerUpdateListener PlayerRevived;

        public BindingList<cPlayer> PlayersList { get; set; }

        public Color TeamColor { get; set; }

        public int TotalScore { get; set; }

        public cFlag Flag { get; set; }

        public cTeam(Color teamColor, Point initialFlagLocation)
        {
            TeamColor = teamColor;
            TotalScore = 0;
            Flag = new cFlag(initialFlagLocation);
            PlayersList = new BindingList<cPlayer>();
            PlayersList.ListChanged += new ListChangedEventHandler(PlayersList_ListChanged);
        }

        void PlayersList_ListChanged(object sender, ListChangedEventArgs e)
        {
            if (e.ListChangedType == ListChangedType.ItemAdded)
            {
                PlayersList[e.NewIndex].LocationUpdate += new cPlayer.PlayerUpdateListener(OnPlayerLocationUpdated);
                PlayersList[e.NewIndex].PlayerHasFlag += new cPlayer.PlayerUpdateListener(OnPlayerHasFlag);
                PlayersList[e.NewIndex].PlayerIsDead += new cPlayer.PlayerUpdateListener(OnPlayerIsDead);
                PlayersList[e.NewIndex].PlayerReturnedFlag += new cPlayer.PlayerUpdateListener(OnPlayerReturnedFlag);
                PlayersList[e.NewIndex].PlayerInSpawnPoint += new cPlayer.PlayerUpdateListener(OnPlayerInSpawnPoint);
                PlayersList[e.NewIndex].PlayerRevived += new cPlayer.PlayerUpdateListener(OnPlayerRevived);
            }
            if (e.ListChangedType == ListChangedType.ItemDeleted)
            {
                PlayersList[e.NewIndex].LocationUpdate -= new cPlayer.PlayerUpdateListener(OnPlayerLocationUpdated);
                PlayersList[e.NewIndex].PlayerHasFlag -= new cPlayer.PlayerUpdateListener(OnPlayerHasFlag);
                PlayersList[e.NewIndex].PlayerIsDead -= new cPlayer.PlayerUpdateListener(OnPlayerIsDead);
                PlayersList[e.NewIndex].PlayerReturnedFlag -= new cPlayer.PlayerUpdateListener(OnPlayerReturnedFlag);
                PlayersList[e.NewIndex].PlayerInSpawnPoint -= new cPlayer.PlayerUpdateListener(OnPlayerInSpawnPoint);
                PlayersList[e.NewIndex].PlayerRevived -= new cPlayer.PlayerUpdateListener(OnPlayerRevived);
            }
        }

        private void OnPlayerRevived(cPlayer pl)
        {
            if (PlayerRevived != null)
                PlayerRevived(this, pl);
        }

        private void OnPlayerInSpawnPoint(cPlayer pl)
        {
            if (PlayerInSpawnPoint != null)
                PlayerInSpawnPoint(this, pl);
        }

        private void OnPlayerReturnedFlag(cPlayer pl)
        {
            if (PlayerReturnedFlag != null)
                PlayerReturnedFlag(this, pl);
        }

        private void OnPlayerIsDead(cPlayer pl)
        {
            if (PlayerIsDead != null)
                PlayerIsDead(this, pl);
        }

        private void OnPlayerHasFlag(cPlayer pl)
        {
            Flag.Location = pl.GetCurrLocation();

            if (PlayerHasFlag != null)
                PlayerHasFlag(this, pl);
        }

        public void OnPlayerLocationUpdated(cPlayer pl)
        {
            if (PlayerLocationUpdate != null)
                PlayerLocationUpdate(this, pl);
        }

        public void AddPlayer(int playerID, string name, string picturePath, int startPort)
        {
            PlayersList.Add(new cPlayer(playerID, name, picturePath, startPort));
        }

        public void RefreshAllConnections(int startPort)
        {
            foreach (cPlayer player in PlayersList)
            {
                player.RefreshConnection(startPort);
            }
        }
    }
}
